package org.xtext.runtime.plan;

import is.lill.acre.message.IACREMessage;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.xtext.runtime.formula.Predicate;
import org.xtext.runtime.interpreter.Agent;
import org.xtext.runtime.messaging.AstraMessage;
import org.xtext.runtime.term.ITerm;
import org.xtext.runtime.term.Term;
import org.xtext.runtime.term.Variable;
import org.xtext.runtime.util.Bindings;
import org.xtext.runtime.util.EvaluateTermsVisitor;

/**
 * Implements the plan step for invoking an EIS action. 
 * @author rem
 *
 */
public class AcreDenyCancelStep implements IPlanStep {
	private ITerm cid;
	
	public AcreDenyCancelStep(ITerm cid) {
		this.cid = cid;
	}
	
	@Override
	public AcreDenyCancelStep apply(Bindings set) {
		cid = cid.apply(set);
		return this;
	}

   @SuppressWarnings ( "unchecked")
   @Override
   public void handle( Agent agent, PlanStack planStack ) {
      EvaluateTermsVisitor visitor = new EvaluateTermsVisitor( agent );
      Term<String> c_id = (Term<String>) cid.accept( visitor );

      IACREMessage am = agent.getConversationManager().failCancel( c_id.value() );
      if ( am != null ) {
         AstraMessage toSend = new AstraMessage();
         toSend.setPerformative( am.getPerformative() );
         toSend.setSender( am.getSender().getName() );
         toSend.addReceiver( am.getReceiver().getName() );
         toSend.setContent( new Predicate( "", new ITerm[0] ) ); // ACRE cancel messages have no content
         toSend.setLanguage( am.getLanguage() );
         toSend.setProtocol( am.getProtocol().toString() );
         toSend.setConversationId( am.getConversationIdentifier() );
         toSend.setInReplyTo( am.getInReplyTo() );
         agent.messageService().send( toSend ); // we only have local message passing so this never returns false
      }
      else {
         agent.addBelief( new Predicate( "denyCancelFailed", new ITerm[] { Term.newInstance( c_id.value() ) } ) );
         planStack.fail();
      }
   }


	@Override
	public String toString(String tabs) {
		return tabs + "acre_deny_cancel(" + cid + ")";
	}
	
	public String toFullString(String tabs) {
		return toString(tabs);
	}
	
	@Override
	public Set<Variable> variables() {
		Set<Variable> vars = new HashSet<Variable>();
		if (cid instanceof Variable) vars.add((Variable) cid);
		return vars;
	}

	@Override
	public AcreDenyCancelStep copy(Map<String, Variable> vars) {
		return new AcreDenyCancelStep(cid.copy(vars));
	}

	public String toString() {
		return toString("");
	}

	@Override
	public void reset() {
	}
}